package com.thread.threadfirst.google.guava;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 注意：expireAfterAccess(long, TimeUnit) 和 expireAfterWrite(long, TimeUnit) 对某个key做访问/写操作都会刷新该cache缓存过期时间。
 * 注意：asMap()视图是不会刷新访问时间的。
 */
public class CacheManager {

    public static LoadingCache<Long,Object> cache= CacheBuilder.newBuilder()
            .concurrencyLevel(1)
//            .expireAfterAccess(5,TimeUnit.SECONDS)
            .expireAfterWrite(5, TimeUnit.SECONDS)
//            .refreshAfterWrite(3,TimeUnit.SECONDS)//在getIfPresent()时判断是否超过上次刷新时间的3s 是的话调用load自动刷新cache
            .build(new CacheLoader<Long, Object>() {
                @Override
                public Object load(Long s) throws Exception {
//                    checkNotNull(s);
                    Object obj=new Object();
                    System.out.println("load method……key "+s+" value "+obj);
                    return obj;
                }
            });

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        new Thread(()->{
            for (;;){
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                System.out.println(sdf.format(new Date())+" size "+cache.size());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

        cache.put(1L,new Object());
        System.out.println(sdf.format(new Date())+" write key:1 ,value:"+cache.getIfPresent(1L));
        Thread.sleep(3000);

       cache.put(1L,new Object());
        System.out.println(sdf.format(new Date()) +" refresh 1, key:1 ,value:"+cache.getIfPresent(1L));
        Thread.sleep(3000);

        cache.put(1L,new Object());
        System.out.println(sdf.format(new Date()) +" refresh 2, key:1 ,value:"+cache.getIfPresent(1L));
        Thread.sleep(3000);

        cache.put(1L,new Object());
        System.out.println(sdf.format(new Date()) +" refresh 3, key:1 ,value:"+cache.getIfPresent(1L));
        Thread.sleep(3000);

        cache.put(2L,new Object());
        System.out.println(sdf.format(new Date()) +" after refresh 1, key:1 ,value:"+cache.getIfPresent(1L)+" write key:2 ,value:"+cache.getIfPresent(2L));
        Thread.sleep(3000);

        System.out.println(sdf.format(new Date()) +" after refresh 2, key:1 ,value:"+cache.getIfPresent(1L)+" after write 1, key:2 ,value:"+cache.getIfPresent(2L));
        Thread.sleep(3000);
        System.out.println(sdf.format(new Date()) +" after refresh 3, key:1 ,value:"+cache.getIfPresent(1L)+" after write 2, key:2 ,value:"+cache.getIfPresent(2L));
        Thread.sleep(3000);
        System.out.println(sdf.format(new Date()) +" after refresh 4, key:1 ,value:"+cache.getIfPresent(1L)+" after write 3, key:2 ,value:"+cache.getIfPresent(2L));
//        Thread.sleep(10000);
//
//        System.out.println("after 10s getIfPresent "+cache.getIfPresent(2L)+"get "+cache.get(1L));

    }
}
